package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysRoleDTO;
import com.nineclock.system.easyexcel.ExcelMember;
import com.nineclock.system.easyexcel.MemberParseListener;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
@Slf4j
public class SysCompanyUserServiceImpl implements SysCompanyUserService {

    @Autowired
    SysCompanyUserMapper companyUserMapper;

    @Override
    public SysCompanyUserDTO getCurrentAdmin() {
        //获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        SysCompanyUser currentAdmin = companyUserMapper.getCurrentAdmin(companyId);
        if(currentAdmin == null){
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }
        return BeanHelper.copyProperties(currentAdmin, SysCompanyUserDTO.class);
    }

    /**
     * 查询当前企业的所有员工信息
     * @return
     */
    @Override
    public List<SysCompanyUserDTO> queryCompanyUserList() {
        //获取 企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //获取当前企业的所有员工信息
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        wrapper.eq(SysCompanyUser::getEnable, 1);

        List<SysCompanyUser> companyUserList = companyUserMapper.selectList(wrapper);
        // companyUserList == null
        if(CollectionUtil.isEmpty(companyUserList)){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        return BeanHelper.copyWithCollection(companyUserList, SysCompanyUserDTO.class);
    }

    @Autowired
    SysDepartmentMapper departmentMapper;

    /**
     * 1. 健壮性判断
     * 2. 查询该部门下的子部门 id 集合（递归）
     * 3. 分页查询
     * 4. 封装结果返回
     * @param page
     * @param pageSize
     * @param keyword
     * @param departmentId
     * @return
     */
    @Override
    public PageResult<SysCompanyUserDTO> members(Integer page, Integer pageSize, String keyword, Long departmentId) {
        //存储部门以及子部门的id集合
        List<Long> departmentIds = new ArrayList<>();
        if(departmentId != 0){
            departmentIds.add(departmentId);
        }
        //查找子部门id集合
        this.queryChildDepartmentIds(departmentId, departmentIds);

        //分页参数
        Page<SysCompanyUser> companyUserPage = new Page<>(page , pageSize);
        //其他条件
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        // 关键词 条件
        if(keyword != null && keyword.length() != 0){
            wrapper.and(wrapper1 -> {
                wrapper1.like(SysCompanyUser::getUserName, keyword)
                        .or().like(SysCompanyUser::getWorkNumber, keyword)
                        .or().like(SysCompanyUser::getMobile, keyword);
            });
        }
        // 企业id
        wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        // 部门id集合
        wrapper.in(SysCompanyUser::getDepartmentId, departmentIds);
        //分页查询
        companyUserPage = companyUserMapper.selectPage(companyUserPage, wrapper);
        //获取要展示的数据
        List<SysCompanyUser> companyUserList = companyUserPage.getRecords();

        if(CollectionUtil.isNotEmpty(companyUserList)){
            List<SysCompanyUserDTO> companyUserDTOList = BeanHelper.copyWithCollection(companyUserList, SysCompanyUserDTO.class);
            //封装pageResult
            PageResult<SysCompanyUserDTO> pageResult = new PageResult<>();
            pageResult.setTotal(companyUserPage.getTotal());
            pageResult.setTotalPage(companyUserPage.getPages());
            pageResult.setRows(companyUserDTOList);
            return pageResult;
        }
        return new PageResult<>();
    }

    @Override
    public void parseExcel(MultipartFile excelFile) throws IOException {
        EasyExcel.read(excelFile.getInputStream(), ExcelMember.class , new MemberParseListener(this))
                .sheet(0)
                .doRead();
    }

    @Autowired
    SysUserMapper userMapper;

    @Autowired
    SysRoleMapper roleMapper;

    @Autowired
    SysCompanyUserRoleMapper companyUserRoleMapper;

    /**
     *
     * @param data
     */
    @Override
    public void importData(List<ExcelMember> data) {
        if( data != null){
            for (ExcelMember member : data) {
                //判断 手机号和邮箱 是否已存在
                LambdaQueryWrapper<SysUser> userQw = new LambdaQueryWrapper<>();
                userQw.eq(SysUser::getMobile, member.getMobile())
                      .or()
                      .eq(SysUser::getEmail, member.getEmail());
                Integer count = userMapper.selectCount(userQw);
                if(count > 0){
                    throw new NcException(ResponseEnum.USER_MOBILE_EMAIL_EXISTS);
                }

                //判断工号是否重复
                LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
                companyUserQw.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
                companyUserQw.eq(SysCompanyUser::getWorkNumber, member.getWorkNumber());

                Integer count1 = companyUserMapper.selectCount(companyUserQw);
                if(count1 > 0){
                    throw new NcException(ResponseEnum.WROK_NUM_EXISTS);
                }


                //新增用户
                SysUser user = new SysUser();
                user.setUsername(member.getName());
                user.setEmail(member.getEmail());
                user.setMobile(member.getMobile());
                //初始密码
                user.setPassword(new BCryptPasswordEncoder().encode("123456"));
                user.setCreateTime(new Date());
                user.setStatus((short)1);
                user.setLastLoginCompanyId(CurrentUserHolder.get().getCompanyId());

                userMapper.insert(user);

                //新增员工
                SysCompanyUser companyUser = new SysCompanyUser();
                companyUser.setUserName(member.getName());
                companyUser.setMobile(member.getMobile());
                companyUser.setEmail(member.getEmail());
                companyUser.setCompanyId(CurrentUserHolder.get().getCompanyId());
                companyUser.setCompanyName(CurrentUserHolder.get().getCompanyName());
                companyUser.setEnable((short)1);
                companyUser.setRemark(member.getDesc());
                companyUser.setCreateTime(new Date());
                companyUser.setTimeEntry(member.getEntryTime());
                companyUser.setPost(member.getPosition());
                companyUser.setOfficeAddress(member.getWorkAddr());
                companyUser.setUserId(user.getId());
                companyUser.setWorkNumber(member.getWorkNumber());

                //根据部门名称 查询部门对象
                LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
                wrapper.eq(SysDepartment::getName, member.getDepartmentName());
                SysDepartment department = departmentMapper.selectOne(wrapper);

                if(department != null){
                    //设置部门信息
                    companyUser.setDepartmentId(department.getId());
                    companyUser.setDepartmentName(department.getName());
                }
                companyUserMapper.insert(companyUser);

                //维护员工和角色的关系
                LambdaQueryWrapper<SysRole> roleQw = new LambdaQueryWrapper<>();
                roleQw.eq(SysRole::getCompanyId, CurrentUserHolder.get().getCompanyId());
                roleQw.eq(SysRole::getRoleDesc, member.getRoleName());

                SysRole role = roleMapper.selectOne(roleQw);
                if(role != null){
                    SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
                    companyUserRole.setCompanyUserId(companyUser.getId());
                    companyUserRole.setCompanyId(CurrentUserHolder.get().getCompanyId());
                    companyUserRole.setRoleId(role.getId());

                    companyUserRoleMapper.insert(companyUserRole);
                }
            }
        }
    }

    @Override
    public SysCompanyUserDTO findCompanyUserByMobile(String mobile) {
        if(mobile == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysCompanyUser::getMobile, mobile);

        SysCompanyUser companyUser = companyUserMapper.selectOne(wrapper);
        if(companyUser == null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        return BeanHelper.copyProperties(companyUser, SysCompanyUserDTO.class);
    }

    @Override
    public Integer queryUserCountByDepartmentIds(List<Long> departmentIds) {
        //如果部门id 为 空， 则返回 0
        if(CollectionUtil.isEmpty(departmentIds)){
            return 0;
        }

        //定义id集合， 装载 当前部门以及子部门id集合
        List<Long> ids = new ArrayList<>();
        //把当前部门id添加进去
        ids.addAll(departmentIds);
        //循环 所有的部门， 查询每个部门的所有的子部门
        for (Long departmentId : departmentIds) {
            this.queryChildDepartmentIds(departmentId, ids);
        }
        //统计部门下的员工数量
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.in(SysCompanyUser::getDepartmentId, ids);

        Integer count = companyUserMapper.selectCount(wrapper);
        return count;
    }

    @Override
    public List<SysCompanyUserDTO> queryUser(Long companyId, Long userId) {
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        if(companyId != null){
            wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        }
        if(userId != null){
            wrapper.eq(SysCompanyUser::getUserId ,userId);
        }
        wrapper.eq(SysCompanyUser::getEnable, 1);

        List<SysCompanyUser> companyUserList = companyUserMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(companyUserList)){
            List<SysCompanyUserDTO> companyUserDTOList = BeanHelper.copyWithCollection(companyUserList, SysCompanyUserDTO.class);
            //循环查询 每位员工的角色
            for (SysCompanyUserDTO companyUserDTO : companyUserDTOList) {
                List<SysRole> roleList = roleMapper.selectRoleList(companyUserDTO.getCompanyId(), companyUserDTO.getId());
                if(CollectionUtil.isNotEmpty(roleList)){
                    companyUserDTO.setRoles(BeanHelper.copyWithCollection(roleList, SysRoleDTO.class));
                }
            }

            return companyUserDTOList;
        }
        return null;
    }

    //查询子部门的id 集合
    public void queryChildDepartmentIds(Long departmentId, List<Long> departmentIds){
        //查询子部门
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getParentId, departmentId );
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        //获取子部门列表
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(departmentList)){
            //抽取部门id
            //map: 映射
            //collect： 指定要转换的集合类型
            List<Long> ids = departmentList.stream().map(department -> {
                return department.getId();
            }).collect(Collectors.toList());

            departmentIds.addAll(ids);
            for (Long id : ids) {
                this.queryChildDepartmentIds(id, departmentIds);
            }
        }
    }
}
